//
//  server_send_reply.hpp
// ~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2013-2014 Razvan Coca (razvan dot coca at  gmail dot com)
// This is mostly generated code. Generator is distributed under GPL. Edit it to suit your needs.
// 


#ifndef server_send_reply_hpp
#define server_send_reply_hpp
#include <boost/bind.hpp>
#include <boost/bind/protect.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <boost/asio.hpp>

#include "patterns/command.hpp"
#include "patterns/handlers.hpp"

#include "logging/logging.hpp"

namespace pcmd=patterns::command;
namespace phdl=patterns::handlers;
namespace ba=boost::asio;
namespace bs=boost::system;
namespace bt=boost::posix_time;

#include "components/defs/util_types.hpp"
#include "components/defs/server_processor.hpp"
#include "components/protocol/create_enc_service_reply.hpp"
#include "components/network/send_enc_pb_message.hpp"

#include "components/defs/handler_types.hpp"

namespace components{
namespace protocol{



class server_send_reply :public boost::enable_shared_from_this<server_send_reply>, private boost::noncopyable
{
private:
    std::string name_;

    ba::io_service& ios_;

    crypto_buf_t& iv_;

    crypto_buf_t& key_;

    stats_message_server_processor& message_processor_;

    ba::ip::udp::socket& msocket_;

    udp_endpoint_t& mgroup_;

    std::string send_buf_;

    boost::shared_ptr<components::network::send_enc_pb_message> send_enc_pb_message_;

    boost::shared_ptr<components::protocol::create_enc_service_reply> create_enc_service_reply_;

    server_send_reply (ba::io_service& ios, crypto_buf_t& iv, crypto_buf_t& key, stats_message_server_processor& message_processor, ba::ip::udp::socket& msocket, udp_endpoint_t& mgroup) ;

    pcmd::action_t op_create_enc_service_reply;



public:
    typedef boost::shared_ptr<server_send_reply> pointer;

    bool cancel () ;

    static boost::shared_ptr<server_send_reply> create (ba::io_service& ios, crypto_buf_t& iv, crypto_buf_t& key, stats_message_server_processor& message_processor, ba::ip::udp::socket& msocket, udp_endpoint_t& mgroup) ;

    void handle_create_enc_service_reply (const crypto_error& eec) ;

    void handle_send_enc_pb_message (const bs::error_code& ec, std::size_t bytes_transferred) ;

    void init_components () ;

    virtual  ~server_send_reply () ;
    template<typename Handler >
    void adapt_send(Handler handler,const bs::error_code& ec, std::size_t bytes_transferred)
    {
        CryptoPP::Exception eec(CryptoPP::Exception::NOT_IMPLEMENTED,std::string("Success"));
        handler(ec,eec);
    }
    template<typename Handler >
    void adapt_encrypt(Handler handler,const crypto_error& eec)
    {
        bs::error_code ec;
        handler(ec,eec);
    }
 template<typename Handler >
      bool exec(Handler& handler) {
        try{
            LOG(INFO)<<name_<<"::"<<__FUNCTION__;

            phdl::crypto_handler_t
                bound_handle_create_enc_service_reply = boost::bind(&server_send_reply::handle_create_enc_service_reply,shared_from_this(),_1);
            phdl::transfer_handler_t
                bound_handle_send_enc_pb_message = boost::bind(&server_send_reply::handle_send_enc_pb_message,shared_from_this(),_1,_2);
            phdl::transfer_handler_t
                    top_send=boost::bind(&server_send_reply::adapt_send<Handler>,shared_from_this(),boost::protect(handler),_1,_2);
            phdl::crypto_handler_t
                    top_encr=boost::bind(&server_send_reply::adapt_encrypt<Handler>,shared_from_this(),boost::protect(handler),_1);

            phdl::transfer_handler_t
                    composed_send=phdl::branch_compose(bound_handle_send_enc_pb_message,top_send,{});
            pcmd::action_t op_send_enc_pb_message = pcmd::wrap(send_enc_pb_message_,boost::ref(send_buf_),composed_send);

            phdl::crypto_handler_t
                    composed_encr=phdl::branch_compose(bound_handle_create_enc_service_reply,top_encr,op_send_enc_pb_message,{0});
            op_create_enc_service_reply = pcmd::wrap(create_enc_service_reply_,boost::ref(send_buf_),composed_encr);
            return pcmd::invoke(op_create_enc_service_reply);
        }
        catch(std::exception &e){
           LOG(WARNING)<<name_<<"::"<<__FUNCTION__<<":"<<e.what();
           cancel();
           return false;
        }
        
    }
};

}//end namespace protocol
}//end namespace components

#endif /*#ifdef server_send_reply_hpp*/
